
#pragma once
#include "SSCalculator.h"
#include "include/SSCalculatorIF.h"
#include "include/SSSingleCalendar.h"
using namespace ssCalculator;

class SSCALCULATOR_API CSSCalculator {
 public:
  CSSCalculator();
  ~CSSCalculator();
  static void destory();

 public:
  //-------------------------------------------------------------------
  // set data
  static void setBondFundamentalInfo(
      const std::vector<SSSingleRawBondFundamentalInfo>& all_info);
  static void addBondFundamentalInfo(
      const std::vector<SSSingleRawBondFundamentalInfo>& all_info);
  static void setInterestRate(
      const std::vector<SSSingleInterestRate>& all_rates);
  static void setCalendar(const std::vector<SSSingleCalendar>& all_calendars);

  // simple calculation
  static double accruedAmount(const std::string& bond_Key,
                              const std::string& settlementDate);

  static double dirtyPriceToCleanPrice(const std::string& bond_Key,
                                       const std::string& settlementDate,
                                       double dirtyPrice);
  static double ytmToCleanPrice(const std::string& bond_Key,
                                const std::string& settlementDate, double ytm);
  static double marketSpreadToCleanPrice(const std::string& bond_Key,
                                         const std::string& settlementDate,
                                         double marketSpread);
  static double ytcToCleanPrice(const std::string& bond_Key,
                                const std::string& settlementDate, double ytc);
  static double ytpToCleanPrice(const std::string& bond_Key,
                                const std::string& settlementDate, double ytp);

  static double cleanPriceToDirtyPrice(const std::string& bond_Key,
                                       const std::string& settlementDate,
                                       double cleanPrice);
  static double cleanPriceToYTM(const std::string& bond_Key,
                                const std::string& settlementDate,
                                double cleanPrice);
  static double cleanPriceToMarketSpread(const std::string& bond_Key,
                                         const std::string& settlementDate,
                                         double cleanPrice);
  static double cleanPriceToYTC(const std::string& bond_Key,
                                const std::string& settlementDate,
                                double cleanPrice);
  static double cleanPriceToYTP(const std::string& bond_Key,
                                const std::string& settlementDate,
                                double cleanPrice);

  static double notional(const std::string& bond_Key, const std::string& date);

  // cashflows
  static std::vector<SSSingleCashflow> cashflowsTable(
      const std::string& bond_Key, const std::string& settlementDate);

  // basic calculation page
  static bool isFRNBond(const std::string& bond_Key);  // 判断是否是浮动债券
  static bool isOptionEmbedded(
      const std::string& bond_Key,
      const std::string& settlementDate);  // 判断是否含权
  static bool isYTCAvailable(const std::string& bond_Key,
                             const std::string& settlementDate);
  static bool isYTPAvailable(const std::string& bond_Key,
                             const std::string& settlementDate);
  static bool isListed(const std::string& bond_Key, const std::string& today);
  static double prevailingRate(
      const std::string& bond_Key,
      const std::string& settlementDate);  // 当前基础利率

  static SSBasicCalculationPage basicPageInitialize(
      const std::string& bond_Key,
      const std::string& settlementDate);  // 价格试算初始化
  static SSBasicCalculationPage setCouponRateSpread(
      const std::string& bond_Key, const std::string& settlementDate,
      double couponRateSpread, double indexRate);
  static SSBasicCalculationPage setIndexRate(const std::string& bond_Key,
                                             const std::string& settlementDate,
                                             double couponRateSpread,
                                             double indexRate);
  static SSBasicCalculationPage clickPrevailingRate(
      const std::string& bond_Key, const std::string& settlementDate,
      double couponRateSpread);

  static SSBasicCalculationPage cleanPriceToAll(
      const std::string& bond_Key, const std::string& settlementDate,
      double couponRateSpread, double indexRate,
      double cleanPrice);  // 净价（基础利率为空，传无效值'-999'）
  static SSBasicCalculationPage dirtyPriceToAll(
      const std::string& bond_Key, const std::string& settlementDate,
      double couponRateSpread, double indexRate, double dirtyPrice);
  static SSBasicCalculationPage ytmToAll(const std::string& bond_Key,
                                         const std::string& settlementDate,
                                         double couponRateSpread,
                                         double indexRate, double ytm);
  static SSBasicCalculationPage marketSpreadToAll(
      const std::string& bond_Key, const std::string& settlementDate,
      double couponRateSpread, double indexRate, double marketSpread);
  static SSBasicCalculationPage ytcToAll(const std::string& bond_Key,
                                         const std::string& settlementDate,
                                         double couponRateSpread,
                                         double indexRate, double ytc);
  static SSBasicCalculationPage ytpToAll(const std::string& bond_Key,
                                         const std::string& settlementDate,
                                         double couponRateSpread,
                                         double indexRate, double ytp);

  // rebate mode
  static SSBasicCalculationPage rebateToAll(const std::string& bond_Key,
                                            const std::string& settlementDate,
                                            double couponRateSpread,
                                            double indexRate, double quotedYTM,
                                            double rebate);

  static double futurePriceByDPAndIRR(const std::string& bond_Key,
                                      const std::string& tradeDate,
                                      const std::string& settlementDate,
                                      double convertFactor, double dirtyPrice,
                                      double irr);

  static double dirtyPriceByFPAndIRR(const std::string& bond_Key,
                                     const std::string& tradeDate,
                                     const std::string& settlementDate,
                                     double convertFactor, double futurePrice,
                                     double irr);
  /*	// rebate mode
          static string listedDate (const std::string& bond_Key) ;
          static SSBasicCalculationPage setCouponRateRebateMode (const
     std::string& bond_Key, double coupon_Rate_Spread) ; static
     SSBasicCalculationPage basicPageInitializeRebateMode(const std::string&
     bond_Key) ;
          // new Issue
          static SSBasicCalculationPage rebateToAllNewIssueRebateMode (const
     std::string& bond_Key, double rebate, double indexRate, double
     coupon_Rate_Spread) ; static SSBasicCalculationPage
     dirtyPriceToAllNewIssueRebateMode (const std::string& bond_Key, double
     dirtyPrice, double indexRate, double coupon_Rate_Spread) ; static
     SSBasicCalculationPage ytmToAllNewIssueRebateMode (const std::string&
     bond_Key, double ytm, double indexRate, double coupon_Rate_Spread) ; static
     SSBasicCalculationPage marketSpreadToAllNewIssueRebateMode (const
     std::string& bond_Key, double marketSpread, double indexRate, double
     coupon_Rate_Spread) ; static SSBasicCalculationPage
     ytcToAllNewIssueRebateMode (const std::string& bond_Key, double ytc, double
     indexRate, double coupon_Rate_Spread) ; static SSBasicCalculationPage
     ytpToAllNewIssueRebateMode (const std::string& bond_Key, double ytp, double
     indexRate, double coupon_Rate_Spread) ;
          // add Issue
          static SSBasicCalculationPage dirtyPriceToAllAddIssueRebateMode (const
     std::string& bond_Key, double dirtyPrice, double indexRate, double
     coupon_Rate_Spread, double rebate) ; static SSBasicCalculationPage
     ytmToAllAddIssueRebateMode (const std::string& bond_Key, double ytm, double
     indexRate, double coupon_Rate_Spread, double rebate) ; static
     SSBasicCalculationPage marketSpreadToAllAddIssueRebateMode (const
     std::string& bond_Key, double marketSpread, double indexRate, double
     coupon_Rate_Spread, double rebate) ; static SSBasicCalculationPage
     ytcToAllAddIssueRebateMode (const std::string& bond_Key, double ytc, double
     indexRate, double coupon_Rate_Spread, double rebate) ; static
     SSBasicCalculationPage ytpToAllAddIssueRebateMode (const std::string&
     bond_Key, double ytp, double indexRate, double coupon_Rate_Spread, double
     rebate) ;
  */
  // holding period yield page
  // trade condition --> basic calculation page

  // holding condition
  static std::vector<SSHoldingPeriodInterest> holdingPeriodInterests(
      const std::string& startDate, const std::string& endDate,
      const std::string& indexID, double spread, int fixingPeriodNumber,
      const std::string& fixingPeriodUnit, const std::string& simpleCompound,
      const std::string& interestBasis, int preceeds, double notional);
  static double holdingCost(const std::vector<SSHoldingPeriodInterest>& vct);
  // result
  static SSHoldingPeriodResult holdingPeriodResult(
      const std::string& bond_Key, const std::string& startDate,
      const std::string& endDate, const std::string& today, double notional,
      double startCleanPrice, double startAccruedInterest,
      double startFrontDeskCommission, double startBackStageCommission,
      double endCleanPrice, double endAccruedInterest,
      double endFrontDeskCommission, double endBackStageCommission,
      double interestTax, double businessTax, double holdingCost,
      bool buyThenSell, int payHoldingCost);

  static double impliedRepoRate(const std::string& bond_Key,
                                const std::string& tradeDate,
                                const std::string& settlementDate,
                                double futurePrice, double convertFactor,
                                double dirtyPrice);

  static std::string exceptions();
};
